<template>
  <div class="role_box">
    <div class="role_title">角色管理</div>
    
    <!-- 搜索区域 -->
    <div class="role_search">
      <div class="search_box">
        <el-input v-model="name_serch" class="name_search input" placeholder="请输入角色名称"/>
      </div>
      <div class="add_box">
        <el-button color="#0052CC" @click="handleAdd">新增</el-button>
      </div>
    </div>

    <!-- 表格区域 -->
    <div class="table-container">
      <el-table 
        :data="pagedData" 
        style="width: 98%; margin-top: 2%; font-size: 13px" 
        border
        v-loading="loading"
      >
        <!-- 表格列定义保持不变 -->
        <el-table-column label="序号" width="60" align="center">
          <template #default="scope">
            {{ (currentPage - 1) * pageSize + scope.$index + 1 }}
          </template>
        </el-table-column>
        <el-table-column label="角色名称" width="140" align="center">
          <template #default="scope">
            {{ scope.row.name }}
          </template>
        </el-table-column>
        <el-table-column label="角色类型" width="180" align="center">
          <template #default="scope">
            <el-tag type="primary">
              {{ getRoleTypeName(scope.row.type) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="可访问菜单" min-width="300" align="center">
          <template #default="scope">
            <div class="menu-container">
              <el-tooltip 
                v-if="scope.row.menus_name && scope.row.menus_name.length"
                :content="scope.row.menus_name.join('、')"
                placement="top"
              >
                <div class="menu-text">{{ scope.row.menus_name.join('、') }}</div>
              </el-tooltip>
              <span v-else class="no-data">无数据</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center">
          <template #default="scope">
            <el-button type="primary" size="small" style="margin-right: 5px;" @click="handleEdit(scope.row)">编辑</el-button>
            <el-button type="danger" size="small" @click="handleDelete(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>
    
    <!-- 分页区域 -->
    <div class="pagination-container">
      <el-pagination 
        background 
        layout="total, prev, pager, next, jumper" 
        :total="total"
        :page-size="pageSize"
        :current-page="currentPage"
        :page-sizes="[10, 20, 50, 100]"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>

    <!-- 新增/编辑角色对话框 -->
    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="500px" @close="handleDialogClose">
      <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
        <el-form-item label="角色名称" prop="name">
          <el-input v-model="form.name" placeholder="请输入角色名称" />
        </el-form-item>
        <el-form-item label="角色类型" prop="type">
          <el-select v-model="form.type" placeholder="请选择角色类型" style="width: 100%">
            <el-option
              v-for="item in roleTypeOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="可访问菜单" prop="menuIdsStr">
          <div class="tree-container">
            <div class="tree-actions">
              <el-checkbox 
                v-model="expandAllChecked" 
                @change="handleExpandAllChange"
              >
                展开/折叠全部
              </el-checkbox>
              <el-checkbox 
                v-model="checkAllChecked" 
                @change="handleCheckAllChange"
              >
                全选/取消全选
              </el-checkbox>
            </div>
            <el-tree
              ref="menuTreeRef"
              :data="menuTreeData"
              show-checkbox
              check-strictly
              node-key="id"
              :default-checked-keys="parsedMenuIds"
              :default-expanded-keys="defaultExpandedKeys"
              :props="treeProps"
              v-loading="menuTreeLoading"
              @check="handleTreeCheck"
            />
          </div>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
        </span>
      </template>
     </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, reactive, nextTick, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { FormInstance, TreeInstance, CheckedChangeParams } from 'element-plus'
import { getRole, addRole,deleteRole } from '../../api/staff/index.js'
import { getMenuList } from '../../api/account/index.js'

// 角色数据接口 - 菜单ID使用逗号分隔的字符串
interface RoleItem {
  id: number
  name: string
  type: number
  menus_name?: string[]
  menuIds?: string // 以逗号分隔的字符串形式存储菜单ID
}

// 原始菜单数据接口
interface RawMenuNode {
  id: number
  pid: number
  icon?: string
  path?: string
  title: string
  [key: string]: any
}

// 树形结构菜单节点接口
interface MenuTreeNode extends RawMenuNode {
  children?: MenuTreeNode[]
}

// 分页相关变量
const currentPage = ref(1)
const pageSize = ref(10)
const total = ref(0)
const loading = ref(false)
const submitLoading = ref(false)
const menuTreeLoading = ref(false)

const allData = ref<RoleItem[]>([])
const name_serch = ref('')

// 对话框相关
const dialogVisible = ref(false)
const dialogType = ref<'add' | 'edit'>('add')
const formRef = ref<FormInstance>()
const menuTreeRef = ref<TreeInstance>()

// 树形控件状态
const expandAllChecked = ref(false)
const checkAllChecked = ref(false)

const treeProps = {
  label: 'title',
  children: 'menus_name' // 改正：使用 children 而不是 menus_name
}

// 菜单树数据和ID映射
const menuTreeData = ref<MenuTreeNode[]>([])
const menuIdSet = ref<Set<number>>(new Set())

// 构建树形结构并创建ID集合
const buildTree = (items: RawMenuNode[]): MenuTreeNode[] => {
  const itemMap = new Map<number, MenuTreeNode>()
  const idSet = new Set<number>()
  
  items.forEach(item => {
    itemMap.set(item.id, { ...item, children: [] })
    idSet.add(item.id)
  })
  
  menuIdSet.value = idSet
  
  const tree: MenuTreeNode[] = []
  
  items.forEach(item => {
    const node = itemMap.get(item.id)
    if (!node) return
    
    const parent = itemMap.get(item.pid)
    if (parent) {
      parent.children?.push(node)
    } else {
      tree.push(node)
    }
  })
  
  return tree
}

// 获取菜单数据
const fetchMenuData = async (forceRefresh = false) => {
  if (menuTreeData.value.length > 0 && !forceRefresh) {
    return
  }
  
  try {
    menuTreeLoading.value = true
    const res = await getMenuList()
    const rawMenuData: RawMenuNode[] = Array.isArray(res.data) ? res.data : []
    menuTreeData.value = buildTree(rawMenuData)
  } catch (error) {
    ElMessage.error('获取菜单数据失败')
    console.error('获取菜单数据失败:', error)
  } finally {
    menuTreeLoading.value = false
  }
}

// 表单数据 - 使用字符串存储菜单ID
const form = reactive({
  id: 0,
  name: '',
  type: 1,
  menuIdsStr: '' // 存储以逗号分隔的菜单ID字符串
})

// 计算属性：将字符串ID转换为数字数组用于树形控件
const parsedMenuIds = computed(() => {
  if (!form.menuIdsStr) return []
  
  return form.menuIdsStr
    .split(',')
    .map(id => parseInt(id, 10))
    .filter(id => !isNaN(id) && menuIdSet.value.has(id))
})

// 默认展开的节点
const defaultExpandedKeys = computed(() => {
  if (expandAllChecked.value) {
    const keys: number[] = []
    const traverse = (nodes: MenuTreeNode[]) => {
      nodes.forEach(node => {
        keys.push(node.id)
        if (node.children && node.children.length > 0) {
          traverse(node.children)
        }
      })
    }
    traverse(menuTreeData.value)
    return keys
  }
  return []
})

// 表单验证规则
const rules = {
  name: [{ required: true, message: '请输入角色名称', trigger: 'blur' }],
  type: [{ required: true, message: '请选择角色类型', trigger: 'change' }]
}

// 角色类型选项
const roleTypeOptions = [
  { value: 1, label: '超管' },
  { value: 2, label: '劳务公司' },
  { value: 3, label: '项目部' },
  { value: 4, label: '审核员' }
]

// 对话框标题
const dialogTitle = computed(() => {
  return dialogType.value === 'add' ? '新增角色' : '编辑角色'
})

// 分页数据处理
const pagedData = computed(() => {
  const startIndex = (currentPage.value - 1) * pageSize.value
  const endIndex = startIndex + pageSize.value
  
  let filteredData = allData.value
  if (name_serch.value) {
    const keyword = name_serch.value.toLowerCase()
    filteredData = filteredData.filter(item => 
      item.name.toLowerCase().includes(keyword)
    )
  }
  
  total.value = filteredData.length
  return filteredData.slice(startIndex, endIndex)
})

// 获取角色列表数据
const fetchRoleData = async () => {
  try {
    loading.value = true
    const res: { data: RoleItem[] } = await getRole()
    allData.value = res.data
  } catch (error) {
    ElMessage.error('获取角色数据失败')
    console.error('获取角色数据失败:', error)
  } finally {
    loading.value = false
  }
}

// 初始加载数据
fetchRoleData()
fetchMenuData()

// 根据角色类型值获取对应的名称
const getRoleTypeName = (type: number) => {
  const roleTypes = {
    1: '超管',
    2: '劳务公司',
    3: '项目部',
    4: '审核员'
  }
  return roleTypes[type as keyof typeof roleTypes] || '未知类型'
}

// 处理展开/折叠全部变化
const handleExpandAllChange = (checked: boolean) => {
  if (menuTreeRef.value) {
    checked ? menuTreeRef.value.expandAll() : menuTreeRef.value.collapseAll()
  }
}

// 处理全选/取消全选变化
const handleCheckAllChange = (checked: boolean) => {
  if (menuTreeRef.value) {
    if (checked) {
      const allKeys: number[] = []
      const traverse = (nodes: MenuTreeNode[]) => {
        nodes.forEach(node => {
          allKeys.push(node.id)
          if (node.children && node.children.length > 0) {
            traverse(node.children)
          }
        })
      }
      traverse(menuTreeData.value)
      menuTreeRef.value.setCheckedKeys(allKeys)
      form.menuIdsStr = allKeys.join(',') // 实时更新字符串
    } else {
      menuTreeRef.value.setCheckedKeys([])
      form.menuIdsStr = '' // 实时更新字符串
    }
  }
}

// 处理树节点勾选事件 - 实时更新字符串格式的菜单ID
const handleTreeCheck = (checkedKeys: CheckedChangeParams['checkedKeys']) => {
  // 实时转换为逗号分隔的字符串，确保在提交前就已处理好
  form.menuIdsStr = (Array.isArray(checkedKeys) ? checkedKeys : [])
    .filter(id => typeof id === 'number')
    .join(',')
}

// 修改 handleAdd 方法
const handleAdd = async () => {
  dialogType.value = 'add'
  dialogVisible.value = true
  
  // 重置表单数据
  Object.assign(form, {
    id: 0,
    name: '',
    type: 1,
    menuIdsStr: ''
  })
  
  expandAllChecked.value = false
  checkAllChecked.value = false
  
  // 确保菜单数据已加载
  await fetchMenuData()
  
  nextTick(() => {
    formRef.value?.resetFields()
    menuTreeRef.value?.setCheckedKeys([])
  })
}

// 修改 handleEdit 方法，优化菜单回显逻辑
const handleEdit = async (row: RoleItem) => {
  dialogType.value = 'edit'
  dialogVisible.value = true
  
  // 确保菜单数据已加载
  await fetchMenuData()
  
  // 处理菜单ID字符串，转换为数字数组并过滤无效ID
  let validMenuIds: number[] = []
  if (row.menus) { // 改正：使用 menus 字段而不是 menuIds
    // 处理可能的数组格式数据（如 "[1,2,3]"）
    let menusStr = row.menus;
    if (menusStr.startsWith('[') && menusStr.endsWith(']')) {
      menusStr = menusStr.substring(1, menusStr.length - 1);
    }
    
    validMenuIds = menusStr
      .split(',')
      .map(id => {
        const trimmed = id.trim();
        return parseInt(trimmed, 10);
      })
      .filter(id => !isNaN(id) && menuIdSet.value.has(id))
  }
  
  // 填充表单数据
  Object.assign(form, {
    id: row.id,
    name: row.name,
    type: row.type,
    menuIdsStr: validMenuIds.join(',') // 转换为字符串
  })
  
  expandAllChecked.value = false
  checkAllChecked.value = false
  
  // 等待DOM更新后设置树的选中状态
  await nextTick()
  
  if (menuTreeRef.value) {
    // 延迟设置选中项，确保树组件已完全渲染
    setTimeout(() => {
      menuTreeRef.value?.setCheckedKeys(validMenuIds)
    }, 50)
  }
}

// 删除角色
const handleDelete = (row: RoleItem) => {
  ElMessageBox.confirm(
    `确定要删除角色 "${row.name}" 吗？`,
    '删除确认',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    }
  ).then(async () => {
    try {
      // 调用删除接口，正确传递参数
      const res = await deleteRole({ id: row.id });
      
      // 检查删除结果
      if (res.code === 1) {
        ElMessage.success('删除成功');
        // 重新获取角色数据以更新列表
        await fetchRoleData();
      } else {
        ElMessage.error(res.message || '删除失败');
      }
    } catch (error: unknown) {
      const errorMessage = error instanceof Error ? error.message : '未知错误';
      ElMessage.error('删除失败: ' + errorMessage);
      console.error('删除角色失败:', error);
    }
  }).catch(() => {
    ElMessage.info('已取消删除');
  });
};

// 修改 handleSubmit 方法中提交前的验证
const handleSubmit = async () => {
  if (!formRef.value) return
  
  submitLoading.value = true
  
  try {
    // 表单验证
    await formRef.value.validate()
    
    // 确保菜单数据已加载
    await fetchMenuData()
    
    // 获取当前选中的菜单ID
    const checkedKeys = menuTreeRef.value?.getCheckedKeys() || []
    const menuIdsStr = (Array.isArray(checkedKeys) ? checkedKeys : [])
      .filter(id => typeof id === 'number')
      .join(',')
  console.log(menuIdsStr,333);
    
    if (dialogType.value === 'add') {
      const params = {
        name: form.name,
        type: form.type,
        menus: menuIdsStr // 使用当前选中的菜单ID字符串
      }
      
      const res = await addRole(params)
      if (res.code === 1) {
        ElMessage.success('新增成功')
      } else {
        ElMessage.error(res.message || '新增失败')
        return
      }
    } else {
      const params = {
        id: form.id,
        name: form.name,
        type: form.type,
        menus: menuIdsStr // 使用当前选中的菜单ID字符串
      }
      
      const res = await addRole(params)
      if (res.code === 1) {
        ElMessage.success('编辑成功')
      } else {
        ElMessage.error(res.message || '编辑失败')
        return
      }
    }
    
    dialogVisible.value = false
    await fetchRoleData()
  } catch (error: unknown) {
    if (error instanceof Error && error.name === 'ValidationError') {
      console.warn('表单验证失败:', error)
    } else {
      const errorMessage = error instanceof Error ? error.message : `${dialogType.value === 'add' ? '新增' : '编辑'}失败`;
      ElMessage.error(errorMessage);
      console.error(`${dialogType.value === 'add' ? '新增' : '编辑'}角色失败:`, error)
    }
  } finally {
    submitLoading.value = false
  }
}

// 关闭对话框时的处理
const handleDialogClose = () => {
  formRef.value?.resetFields()
  expandAllChecked.value = false
  checkAllChecked.value = false
  submitLoading.value = false
}

// 分页事件处理
const handleSizeChange = (val: number) => {
  pageSize.value = val
  currentPage.value = 1
}

const handleCurrentChange = (val: number) => {
  currentPage.value = val
}

// 监听菜单数据变化，确保编辑时能正确回显
watch(menuTreeData, (newVal) => {
  if (newVal.length > 0 && dialogVisible.value && dialogType.value === 'edit') {
    nextTick(() => {
      const validIds = parsedMenuIds.value
      menuTreeRef.value?.setCheckedKeys(validIds)
    })
  }
})
</script>

<style scoped>
/* 样式保持不变 */
.role_box {
  width: 100%;
  background-color: #fff;
  padding: 0 15px;
  box-sizing: border-box;
}

.role_title {
  background: #fff;
  width: 100%;
  height: 60px;
  font-size: 24px;
  font-weight: 500;
  display: flex;
  align-items: center;
  border-bottom: 1px solid #eee;
  margin-bottom: 15px;
  padding-left: 20px;
}

.role_search {
  display: flex;
  justify-content: space-between;
  padding: 0 2%;
  margin-bottom: 10px;
  align-items: center;
}

.name_search {
  width: 280px;
}

.table-container {
  padding: 0 2%;
  min-height: 300px;
}

.pagination-container {
  padding: 20px 2%;
  text-align: right;
}

/* 菜单容器样式 */
.menu-container {
  display: flex;
  justify-content: center;
  overflow: hidden;
}

.menu-text {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
  border-bottom: 1px dotted #409eff;
}

.no-data {
  color: #999;
}

/* 树形控件容器 */
.tree-container {
  width: 100%;
  max-height: 350px;
  overflow-y: auto;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  padding: 10px;
}

.tree-actions {
  display: flex;
  justify-content: space-between;
  margin-bottom: 10px;
  padding-bottom: 5px;
  border-bottom: 1px solid #f2f2f2;
}

/* 按钮样式优化 */
:deep(.el-button) {
  padding: 6px 12px;
}

/* 复选框样式 */
:deep(.el-checkbox) {
  margin-right: 15px;
}

/* 分页 */
.pagination-container{
  display: flex;
  justify-content: center;
}

/* 树形节点样式优化 */
:deep(.el-tree-node) {
  white-space: nowrap;
}

:deep(.el-tree-node__content) {
  height: 32px;
}

:deep(.el-tree-node__label) {
  padding-right: 10px;
}
</style>
